package com.qlslylq.ad.sdk.core.loader;

import android.app.Activity;
import android.view.View;
import android.view.ViewGroup;

import com.bytedance.sdk.openadsdk.AdSlot;
import com.bytedance.sdk.openadsdk.TTAdConstant;
import com.bytedance.sdk.openadsdk.TTAdLoadType;
import com.bytedance.sdk.openadsdk.TTAdNative;
import com.bytedance.sdk.openadsdk.TTSplashAd;
import com.kwad.sdk.api.KsLoadManager;
import com.kwad.sdk.api.KsScene;
import com.kwad.sdk.api.KsSplashScreenAd;
import com.kwad.sdk.api.SdkConfig;
import com.mbridge.msdk.out.MBSplashHandler;
import com.mbridge.msdk.out.MBSplashLoadListener;
import com.mbridge.msdk.out.MBSplashShowListener;
import com.mbridge.msdk.out.MBridgeIds;
import com.qlslylq.ad.sdk.config.CsjMgrHolder;
import com.qlslylq.ad.sdk.config.KsMgrHolder;
import com.qlslylq.ad.sdk.constant.UrlConst;
import com.qlslylq.ad.sdk.core.ad.BaseAd;
import com.qlslylq.ad.sdk.core.interceptor.SplashADListener;
import com.qlslylq.ad.sdk.core.interceptor.WindSplashADListener;
import com.qlslylq.ad.sdk.core.listener.SplashAdListener;
import com.qlslylq.ad.sdk.core.mgr.PoolMgr;
import com.qlslylq.ad.sdk.core.rsp.AdError;
import com.qlslylq.ad.sdk.enums.AdEventSign;
import com.qlslylq.ad.sdk.enums.AdPlatformEnum;
import com.qlslylq.ad.sdk.enums.ErrorEnum;
import com.qlslylq.ad.sdk.model.req.UserBehaviorAddDTO;
import com.qlslylq.ad.sdk.model.rsp.AdPlaceWebConfigureVO;
import com.qlslylq.ad.sdk.net.api.ApiServiceImpl;
import com.qlslylq.ad.sdk.util.DecimalUtils;
import com.qlslylq.ad.sdk.util.DensityUtils;
import com.qlslylq.ad.sdk.util.GsonUtils;
import com.qlslylq.ad.sdk.util.Log;
import com.qq.e.ads.splash.SplashAD;
import com.sigmob.windad.Splash.WindSplashAD;
import com.sigmob.windad.Splash.WindSplashAdRequest;
import com.sigmob.windad.WindAdError;

import static com.qlslylq.ad.sdk.enums.OrientationEnum.PORTRAIT;

/**
 * 开屏广告加载器<br/>
 */
public class SplashAdLoader extends AdLoader<SplashAdListener> {

    //广告容器
    private ViewGroup adContainer;

    //广告容器宽[px]
    private int adContainerWidth;

    //广告容器高[px]
    private int adContainerHeight;

    //请求到展示的最大允许时长(ms)
    private int fetchDelay;

    /**
     * 当前Splash页面的展示必须使用此构造<br/>
     */
    public SplashAdLoader(Activity context, long posId, ViewGroup adContainer, int fetchDelay, SplashAdListener adListener) {
        super(context, posId, adListener);
        if (adContainer == null) {
            throw new IllegalArgumentException("容器参数不能为null");
        }
        if (fetchDelay <= 0) {
            fetchDelay = 5 * 1000;
        }
        this.adContainer = adContainer;
        this.fetchDelay = fetchDelay;
    }

    /**
     * 仅用于Splash前置页面的预加载，禁止使用此构造去展示广告<br/>
     * 即此构造后只能load，不能show与tryAgain<br/>
     */
    public SplashAdLoader(Activity context, long posId, int adContainerWidth, int adContainerHeight, int fetchDelay, SplashAdListener adListener) {
        super(context, posId, adListener);
        if (adContainerWidth <= 0) {
            throw new IllegalArgumentException("容器参数不能为null");
        }
        if (adContainerHeight <= 0) {
            throw new IllegalArgumentException("容器参数不能为null");
        }
        if (fetchDelay <= 0) {
            fetchDelay = 5 * 1000;
        }
        this.fetchDelay = fetchDelay;
        this.adContainerWidth = adContainerWidth;
        this.adContainerHeight = adContainerHeight;
    }

    /**
     * 加载并展示<br/>
     */
    protected void load(AdPlaceWebConfigureVO config) {
        AdPlatformEnum platform = config.getPlatform();
        String posId = config.getPositionId();

        if (platform == AdPlatformEnum.PLATFORM_CSJ) {//穿山甲
            if (adContainer == null) {
                loadCsj(config, adContainerWidth, adContainerHeight);
            } else {
                adContainer.post(() -> {
                    loadCsj(config, adContainer.getWidth(), adContainer.getHeight());
                });
            }
        } else if (platform == AdPlatformEnum.PLATFORM_YLH) {//优量汇
            SplashADListener listener = new SplashADListener() {
                private boolean hasPop = false;

                public void onADLoaded(long expireTimestamp) {
                    PoolMgr.getInstance().push(getAd(), config);

                    getAdListener().onAdLoad();
                    hasPop = true;

                    ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_RETURN_SUCCESS, SplashAdLoader.super.posId));
                }

                //成功展示，不等于有效展示（如广告容器高度不够）
                public void onADPresent() {
                    onAdShowSafety();
                }

                //有效展示(曝光),不提供回调
                public void onADExposure() {
                    ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_EXPOSURE, SplashAdLoader.super.posId));
                }

                //倒计时器,不提供回调
                public void onADTick(long millisUntilFinished) {

                }

                //3中来源：[跳过，倒计时结束，进入广告]，如果是进入了广告，当广告视图不可见时，就会回调(时机：onPause后)
                public void onADDismissed() {
                    getAdListener().onAdDismiss();

                    ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_CLOSE, SplashAdLoader.super.posId));
                }

                public void onADClicked() {
                    getAdListener().onAdClick();

                    ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_CLICK, SplashAdLoader.super.posId));
                }

                public void onNoAD(com.qq.e.comm.util.AdError error) {
                    Log.e(GsonUtils.gsonString(AdError.build(platform, adType, error.getErrorCode(), error.getErrorMsg())));
                    if (!hasPop) {//onADLoaded后   如果广告容器尺寸错误   可能会调onNoAD
                        getAdListener().onAdLoadError(AdError.build(platform, adType, error.getErrorCode(), error.getErrorMsg()));
                    } else {
                        onAdShowErrorSafety(AdError.build(platform, adType, error.getErrorCode(), error.getErrorMsg()), platform, true);
                    }

                    ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_RETURN_FAIL, SplashAdLoader.super.posId));
                }
            };
            SplashAD ad = new SplashAD(context, posId, listener, fetchDelay);
            listener.setAd(ad);
            ad.fetchAdOnly();
        } else if (platform == AdPlatformEnum.PLATFORM_KS) {//快手联盟
            KsScene scene = new KsScene.Builder(DecimalUtils.parseLongSafe(posId))
                    .setBackUrl(UrlConst.BACK_URL_AD) // scheme逆向唤醒协议名设置，与清单中所注册的协议名保持一致即可
                    .screenOrientation(orientation == PORTRAIT ? SdkConfig.SCREEN_ORIENTATION_PORTRAIT : SdkConfig.SCREEN_ORIENTATION_LANDSCAPE)//不起决定性
                    .build();
            KsMgrHolder.get().loadSplashScreenAd(scene, new KsLoadManager.SplashScreenAdListener() {
                public void onSplashScreenAdLoad(KsSplashScreenAd ad) {
                    PoolMgr.getInstance().push(ad, config);

                    getAdListener().onAdLoad();

                    ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_RETURN_SUCCESS, SplashAdLoader.super.posId));
                }

                public void onRequestResult(int adNumber) {

                }

                public void onError(int code, String msg) {
                    Log.e(GsonUtils.gsonString(AdError.build(platform, adType, code, msg)));
                    getAdListener().onAdLoadError(AdError.build(platform, adType, code, msg));

                    ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_RETURN_FAIL, SplashAdLoader.super.posId));
                }
            });
        } else if (platform == AdPlatformEnum.PLATFORM_SIGMOB) {
            WindSplashAdRequest request = new WindSplashAdRequest(posId, null, null);
            request.setDisableAutoHideAd(true);
            request.setFetchDelay((int) (fetchDelay / 1000f));
            WindSplashADListener listener = new WindSplashADListener() {
                public void onSplashAdSuccessLoad() {
                    PoolMgr.getInstance().push(getAd(), config);

                    getAdListener().onAdLoad();

                    ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_RETURN_SUCCESS, SplashAdLoader.super.posId));
                }

                public void onSplashAdFailToLoad(WindAdError error, String msg) {
                    Log.e(GsonUtils.gsonString(AdError.build(platform, adType, error.getErrorCode(), error.getMessage())));
                    getAdListener().onAdLoadError(AdError.build(platform, adType, error.getErrorCode(), error.getMessage()));

                    ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_RETURN_FAIL, SplashAdLoader.super.posId));
                }

                public void onSplashAdSuccessPresent() {
                    onAdShowSafety();

                    ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_EXPOSURE, SplashAdLoader.super.posId));
                }

                public void onSplashAdClicked() {
                    getAdListener().onAdClick();

                    ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_CLICK, SplashAdLoader.super.posId));
                }

                public void onSplashClosed() {
                    getAdListener().onAdDismiss();

                    ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_CLOSE, SplashAdLoader.super.posId));
                }
            };
            WindSplashAD ad = new WindSplashAD(context, request, listener);
            listener.setAd(ad);
            ad.loadAdOnly();
        } else if (platform == AdPlatformEnum.PLATFORM_MINTEGRAL) {
            MBSplashHandler ad = new MBSplashHandler(context, null, config.getPositionId());
            ad.setLoadTimeOut(fetchDelay / 1000);
            ad.setSplashLoadListener(new MBSplashLoadListener() {
                public void onLoadSuccessed(MBridgeIds ids, int reqType) {
                    PoolMgr.getInstance().push(ad, config);

                    getAdListener().onAdLoad();

                    ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_RETURN_SUCCESS, SplashAdLoader.super.posId));
                }

                public void onLoadFailed(MBridgeIds ids, String msg, int reqType) {
                    Log.e(GsonUtils.gsonString(AdError.build(platform, adType, ErrorEnum.ERR_LOAD_FAILD.getId(), msg)));
                    getAdListener().onAdLoadError(AdError.build(platform, adType, ErrorEnum.ERR_LOAD_FAILD.getId(), msg));

                    ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_RETURN_FAIL, SplashAdLoader.super.posId));
                }

                public void isSupportZoomOut(MBridgeIds mBridgeIds, boolean support) {

                }
            });

            ad.setSplashShowListener(new MBSplashShowListener() {
                public void onShowSuccessed(MBridgeIds ids) {
                    onAdShowSafety();

                    ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_EXPOSURE, SplashAdLoader.super.posId));
                }

                public void onShowFailed(MBridgeIds ids, String msg) {
                    Log.e(GsonUtils.gsonString(AdError.build(platform, adType, ErrorEnum.ERR_SHOW_FAILD.getId(), msg)));
                    onAdShowErrorSafety(AdError.build(platform, adType, ErrorEnum.ERR_SHOW_FAILD.getId(), msg), platform, true);
                }

                public void onAdClicked(MBridgeIds ids) {
                    getAdListener().onAdClick();

                    ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_CLICK, SplashAdLoader.super.posId));
                }

                public void onDismiss(MBridgeIds ids, int type) {
                    getAdListener().onAdDismiss();

                    ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_CLOSE, SplashAdLoader.super.posId));
                }

                public void onAdTick(MBridgeIds ids, long millisUntilFinished) {
                }

                public void onZoomOutPlayStart(MBridgeIds mBridgeIds) {

                }

                public void onZoomOutPlayFinish(MBridgeIds mBridgeIds) {

                }
            });
            ad.preLoad();
        }
    }

    /**
     * 加载穿山甲<br/>
     */
    private void loadCsj(AdPlaceWebConfigureVO config, int adContainerWidth, int adContainerHeight) {
        AdPlatformEnum platform = config.getPlatform();
        String posId = config.getPositionId();

        AdSlot adSlot = new AdSlot.Builder()
                .setCodeId(posId)
                .setOrientation(orientation == PORTRAIT ? TTAdConstant.VERTICAL : TTAdConstant.HORIZONTAL)//方向由创建时决定，且不能改变，此处应可省
                .setImageAcceptedSize(adContainerWidth, adContainerHeight)//px
                .setExpressViewAcceptedSize(DensityUtils.px2dp(context, adContainerWidth), DensityUtils.px2dp(context, adContainerHeight))//dp
                .setAdLoadType(TTAdLoadType.PRELOAD)//[实时加载，预加载]
                .build();
        CsjMgrHolder.createAdNative(context).loadSplashAd(adSlot, new TTAdNative.SplashAdListener() {
            public void onSplashAdLoad(TTSplashAd ad) {
                PoolMgr.getInstance().push(ad, config);

                getAdListener().onAdLoad();

                ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_RETURN_SUCCESS, SplashAdLoader.super.posId));
            }

            public void onTimeout() {
                Log.e(GsonUtils.gsonString(ErrorEnum.ERR_NO_AD.rsp(platform, adType)));
                getAdListener().onAdLoadError(ErrorEnum.ERR_NO_AD.rsp(platform, adType));

                ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_RETURN_FAIL, SplashAdLoader.super.posId));
            }

            public void onError(int code, String msg) {
                Log.e(GsonUtils.gsonString(AdError.build(platform, adType, code, msg)));
                getAdListener().onAdLoadError(AdError.build(platform, adType, code, msg));

                ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_RETURN_FAIL, SplashAdLoader.super.posId));
            }

        }, fetchDelay);
    }

    protected void show(BaseAd ad) {
        AdPlaceWebConfigureVO config = ad.getConfig();
        AdPlatformEnum platform = config.getPlatform();
        String posId = config.getPositionId();

        if (adContainer == null) {
            onAdShowErrorSafety(ErrorEnum.ERR_SHOW_SPLASH.rsp(platform, adType), platform, false);
            return;
        }

        adContainer.post(() -> {
            if (platform == AdPlatformEnum.PLATFORM_CSJ) {//穿山甲
                TTSplashAd adThird = (TTSplashAd) ad.getAd();
                if (!context.isFinishing()) {
                    adContainer.addView(adThird.getSplashView());
                    adThird.setSplashInteractionListener(new TTSplashAd.AdInteractionListener() {
                        public void onAdShow(View view, int type) {
                            onAdShowSafety();

                            ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_EXPOSURE, SplashAdLoader.super.posId));
                        }

                        public void onAdTimeOver() {
                            getAdListener().onAdDismiss();

                            ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_CLOSE, SplashAdLoader.super.posId));
                        }

                        public void onAdSkip() {
                            getAdListener().onAdDismiss();

                            ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_CLOSE, SplashAdLoader.super.posId));
                        }

                        public void onAdClicked(View view, int type) {
                            getAdListener().onAdClick();

                            ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_CLICK, SplashAdLoader.super.posId));
                        }
                    });
                }
            } else if (platform == AdPlatformEnum.PLATFORM_YLH) {//优量汇
                SplashAD adThird = (SplashAD) ad.getAd();
                adThird.showAd(adContainer);
            } else if (platform == AdPlatformEnum.PLATFORM_KS) {//快手联盟
                KsSplashScreenAd adThird = (KsSplashScreenAd) ad.getAd();
                View splashView = adThird.getView(context, new KsSplashScreenAd.SplashScreenAdInteractionListener() {
                    public void onAdShowStart() {
                        onAdShowSafety();

                        ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_EXPOSURE, SplashAdLoader.super.posId));
                    }

                    public void onAdShowEnd() {
                        getAdListener().onAdDismiss();

                        ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_CLOSE, SplashAdLoader.super.posId));
                    }

                    public void onAdShowError(int code, String msg) {
                        Log.e(GsonUtils.gsonString(AdError.build(platform, adType, code, msg)));
                        onAdShowErrorSafety(AdError.build(platform, adType, code, msg), platform, true);
                    }

                    public void onSkippedAd() {
                        getAdListener().onAdDismiss();

                        ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_CLOSE, SplashAdLoader.super.posId));
                    }

                    public void onAdClicked() {
                        getAdListener().onAdClick();

                        ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_CLICK, SplashAdLoader.super.posId));
                    }

                    public void onDownloadTipsDialogShow() {

                    }

                    public void onDownloadTipsDialogDismiss() {

                    }

                    public void onDownloadTipsDialogCancel() {

                    }
                });

                if (!context.isFinishing()) {
                    splashView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                            ViewGroup.LayoutParams.MATCH_PARENT));
                    adContainer.addView(splashView);
                }
            } else if (platform == AdPlatformEnum.PLATFORM_SIGMOB) {
                WindSplashAD adThird = (WindSplashAD) ad.getAd();
                if (adThird.isReady()) {
                    adThird.showAd(adContainer);
                } else {
                    Log.e(GsonUtils.gsonString(ErrorEnum.ERR_NOT_READY.rsp(platform, adType)));
                    onAdShowErrorSafety(ErrorEnum.ERR_NOT_READY.rsp(platform, adType), platform, true);
                }
            } else if (platform == AdPlatformEnum.PLATFORM_MINTEGRAL) {
                MBSplashHandler adThird = (MBSplashHandler) ad.getAd();
                if (adThird.isReady()) {
                    adThird.show(adContainer);
                } else {
                    Log.e(GsonUtils.gsonString(ErrorEnum.ERR_NOT_READY.rsp(platform, adType)));
                    onAdShowErrorSafety(ErrorEnum.ERR_NOT_READY.rsp(platform, adType), platform, true);
                }
            }
        });
    }

}
